import 'package:family_expense/features/bank_card/models/bank_card.dart';
import 'package:family_expense/features/bank_card/services/bank_card_service.dart';
import 'package:family_expense/features/bank_card/widgets/add_bank_card.dart';
import 'package:family_expense/features/bank_card/widgets/bank_card_info.dart';
import 'package:family_expense/features/bank_card/widgets/bank_card_shared.dart';
import 'package:family_expense/features/bank_card/widgets/bank_shared.dart';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

class BankCardHome extends StatefulWidget {
  const BankCardHome({super.key});

  @override
  State<BankCardHome> createState() => _BankCardHomeState();
}

class _BankCardHomeState extends State<BankCardHome> {
  final int _pageSize = GeneralConfig.listViewPageSize;

  // Retrieving the data from server.
  final BankCardService _bankCardService = BankCardService();

  // Indicates if display the [CheckListTile] for selection.
  bool _enableItemSelection = false;

  // Current authenticated user.
  User? _user;

  // Used to notify last view that current item has been added or updated.
  bool? _dataUpdated;

  // In order to refresh the list after item changes. Including updated, added or removed.
  late PagingAnimatedListViewLoadController _loadController;

  @override
  void initState() {
    super.initState();

    _getCurrentUser();
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      onPopInvokedWithResult: _onPopInvokedWithResult,
      child: Scaffold(appBar: _buildAppBar(), body: _buildBody()),
    );
  }

  /// Builds app bar.
  PreferredSizeWidget _buildAppBar() {
    return AppBar(
      title: Text(_enableItemSelection ? '删除卡片' : '银行卡片'),
      actions: <Widget>[
        if (_user?.isAccountGroupAdmin == true)
          IconButton(
            icon: _enableItemSelection
                ? Icon(MdiIcons.cancel)
                : Icon(MdiIcons.checkboxMarkedOutline),
            tooltip: _enableItemSelection ? '退出选择模式' : '进入选择模式',
            onPressed: _toggleItemSelection,
          ),
        if (_user?.isAccountGroupAdmin == true)
          IconButton(
            icon: const Icon(Icons.add),
            tooltip: '添加卡片',
            onPressed: _gotoInfoView,
          ),
      ],
    );
  }

  /// Builds main body.
  Widget _buildBody() {
    return PagingAnimatedList(
      pageSize: _pageSize,
      getLoadController: (loadController) => _loadController = loadController,
      retrieveData: (pageIndex) =>
          _bankCardService.queryBasicInfoByAccountGroup(_pageSize, pageIndex!),
      itemBuilder: (context, index, item, animation) => _enableItemSelection
          ? _bulidListTileForDeletion(item)
          : _bulidListTile(item),
    );
  }

  /// Builds the list tile for bank card list view.
  Widget _bulidListTile(BankCard bankCard) {
    return ListTile(
      leading: Hero(
        tag: bankCard.id!,
        transitionOnUserGestures: true,
        child: BankLogo(bankCard.bank!),
      ),
      title: BankCardShared.buildBankCardName(bankCard),
      subtitle: Text(
        bankCard.isCreditCard == true
            ? BankShared.getCreditCardStatementDateRangeDescription(bankCard)
            : '储蓄卡',
      ),
      trailing: const ListTileNavigateNextIcon(),
      onTap: () => _gotoInfoView(id: bankCard.id),
      onLongPress: _user?.isAccountGroupAdmin == true
          ? () {
              // Long press will start item selection if [_enableItemSelection] is false.
              if (!_enableItemSelection) {
                _toggleItemSelection();
              }
            }
          : null,
    );
  }

  /// Displays the list tile for deletion.
  Widget _bulidListTileForDeletion(BankCard bankCard) {
    return ListTile(
      leading: BankLogo(bankCard.bank!),
      title: Text(bankCard.name!),
      trailing: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          bankCard.isCreditCard!
              ? const Chip(
                  padding: EdgeInsets.all(0.0),
                  label: Text('信用卡'),
                  backgroundColor: Colors.lightGreenAccent,
                )
              : Container(),
          SizedBox(
            width: 40.0,
            child: IconButton(
              icon: const Icon(Icons.clear),
              iconSize: 30.0,
              color: Colors.redAccent[200],
              onPressed: () => _deleteBankCard(bankCard),
            ),
          ),
        ],
      ),
    );
  }

  /// Gets current authenticated user.
  Future<void> _getCurrentUser() async {
    final user = await AuthStateService.instance.currentUser;

    if (mounted) {
      setState(() => _user = user);
    }
  }

  /// Checks the data before popping.
  void _onPopInvokedWithResult(bool didPop, dynamic result) {
    if (didPop) {
      return;
    }

    if (_enableItemSelection) {
      _toggleItemSelection();
    } else {
      // Passes the update bank card to previous page for list update.
      NavigatorHelper.pop<bool>(context, _dataUpdated);
    }
  }

  /// Goes to the info view for adding or details.
  Future<void> _gotoInfoView({String? id}) async {
    bool? dataUpdated = false;

    // Gets the updated result from [BankCardInfo] and notify the list item change.
    // [id] is null means adding new data.
    if (id == null) {
      dataUpdated =
          await NavigatorHelper.push<bool>(context, const AddBankCard()) ??
          false;
    } else {
      dataUpdated = await NavigatorHelper.push<bool>(context, BankCardInfo(id));
    }

    if (_dataUpdated == null || _dataUpdated == false) {
      _dataUpdated = dataUpdated;
    }

    if (_dataUpdated == true) {
      // Clears cache and re-init the data again.
      await _bankCardService.reInit();

      // Needs to reset the list.
      _loadController.reset();
    }
  }

  /// Starts item selection if [_enableItemSelection] is true. Or completes item selection if [_enableItemSelection] is true.
  ///
  /// It will change the value of [_enableItemSelection] and show or close the deletion action.
  void _toggleItemSelection() {
    if (mounted) {
      setState(() => _enableItemSelection = !_enableItemSelection);
    }
  }

  /// Deletes all selected payments.
  ///
  /// This is animated view. It animates after item deleted. That's why we do not show [NoItemFound] after deleting.
  void _deleteBankCard(BankCard bankCard) {
    showConfirmDialog(
      context,
      '删除卡片 ${bankCard.name}？',
      onConfirm: () async {
        final isDeleted = await _bankCardService.delete(bankCard.id!);

        if (isDeleted) {
          // Gets the item index in the data list.
          final index = _loadController.getItemIndex(bankCard);

          // Removes the item from the animated list.
          _loadController.removeItem(index, (context, animation) {
            return SizeTransition(
              axis: Axis.vertical,
              sizeFactor: animation,
              child: _bulidListTileForDeletion(bankCard),
            );
          });

          // If has no further data after deletion the selection mode will be canceled.
          if (!_loadController.hasData) {
            _toggleItemSelection();
          }

          _dataUpdated = true;
        } else {
          showToast('卡片 ${bankCard.name} 已被使用，不可删除。');
        }
      },
    );
  }
}
